
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:ui';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart';
import '../config/config.dart';
import './image.dart';

class OssClient {

    static Future<String> uploadFile(File file) async{
        var _sign = {
            "AccessKeyId":OssConfig.secretId,
            "AccessKeySecret":OssConfig.secretKey,
            "host":OssConfig.host
        };
        //创建dio对象
        Dio dio = new Dio();
        //dio的请求配置
        dio.options.responseType = ResponseType.plain;
        dio.options.contentType = "multipart/form-data";
        //文件名
        String path = file.path;
        String fileName = path.lastIndexOf('/') > -1 ? path.substring(path.lastIndexOf('/') + 1) : path;
        String fileKey=await getImageNameByPath(path);
        String policy=getPolicyBase64();
        //创建一个FormData，作为dio的参数
        FormData formData = FormData.fromMap({
            //文件名，随意
            // "Filename": 'flutter-test',
            //"可以填写文件夹名（对应于oss服务中的文件夹）/" + fileName
            "key": fileKey,//上传后的文件名
            "policy": policy,
            "signature": getSignature(_sign['AccessKeySecret']!,policy),
            "OSSAccessKeyId": _sign['AccessKeyId'],
            'x-oss-security-token': "", // 访问是使用STS临时授权，则需要指定该项为SecurityToken的值
            "success_action_status": '200',
            "file":await MultipartFile.fromFile(path, filename:fileName)
        });
        try {
            Response response = await dio.post(_sign['host']!, data: formData);

            if (response.statusCode == 200) {
                print("上传完成");
                return _sign['host']!+'/'+fileKey;
            } else {
                return "";
            }
        } on DioError catch (e) {
            print(e.toString());
            print("get uploadImage error: $e");
			return "";
        }
    }

    static String getPolicyBase64(){
		// var policyText = {
		// 	'expiration': '2069-05-22T03:15:00.000Z', // 设置该Policy的失效时间，超过这个失效时间之后，就没有办法通过这个policy上传文件了
		// 	'conditions': [
		// 		['content-length-range', 0, 100 * 1024 * 1024], // 设置上传文件的大小限制,100mb
		// 	],
		// };
        String policyText='{"expiration": "2069-05-22T03:15:00.000Z","conditions": [["content-length-range", 0, 104857600]]}';
		var policyBase64 = base64.encode(utf8.encode(policyText.toString()));
		return policyBase64;
    }

    static String getSignature(String _accessKeySecret,String policy){
        //进行utf8 编码
        // ignore: non_constant_identifier_names
        List<int> AccessKeySecretUtf8 = utf8.encode(_accessKeySecret);
        //通过hmac,使用sha1进行加密
        List<int> policy_utf8=utf8.encode(policy);
        List<int> signaturePre = new Hmac(sha1, AccessKeySecretUtf8).convert(policy_utf8).bytes;
        //最后一步，将上述所得进行base64 编码
        String signature = base64.encode(signaturePre);
        return signature;
    }

    /*
    * 根据图片本地路径获取图片名称
    * */
    static Future<String> getImageNameByPath(String filePath) async {
        // ignore: null_aware_before_operator
        String name='${OssConfig.defaultPath}${ProjectConfig.env}/';
        DateTime dateTime= DateTime.now();
        String year=dateTime.year.toString();
        String month=dateTime.month.toString();
        String day=dateTime.day.toString();
        name+='$year/$month/$day/';

        String ext=filePath.substring(filePath.lastIndexOf("."),filePath.length);
        if(ext=='.jpg'||ext=='.jpeg'||ext=='.png'){
            Image _image=await ImageUtil.loadImageFromFile(filePath);
            name+='${_image.width}/${_image.height}/';
        }
        name=name+randomString(16)+ext;
        return name;
    }

    static String randomString(len){
        String alphabet = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM';
        int strlenght = len; /// 生成的字符串固定长度
        String left = '';
        for (var i = 0; i < strlenght; i++) {
            // right = right + (min + (Random().nextInt(max - min))).toString();
            left = left + alphabet[Random().nextInt(alphabet.length)];
        }
        return left;
    }
}

